<?php

namespace App\Command;

use App\Modules\CodeDesigner\AbstractFactory\BlackAnimalFactoryImpl;
use App\Modules\CodeDesigner\AbstractFactory\Product\Cat;
use App\Modules\CodeDesigner\AbstractFactoryReflection\FactoryReflection;
use App\Modules\CodeDesigner\AdapterMode\CatAdapterImpl;
use App\Modules\CodeDesigner\AdapterMode\DogAdapterImpl;
use App\Modules\CodeDesigner\AdapterMode\Main;
use App\Modules\CodeDesigner\ComponentMode\Composite;
use App\Modules\CodeDesigner\ComponentMode\Leaf;
use App\Modules\CodeDesigner\Factory\OperationFactory;
use App\Modules\CodeDesigner\Ioc\CommonKeyboard;
use App\Modules\CodeDesigner\Ioc\Computer;
use App\Modules\CodeDesigner\Ioc\Container;
use App\Modules\CodeDesigner\Memento\Caretaker;
use App\Modules\CodeDesigner\Memento\Originator;
use App\Modules\CodeDesigner\ObserveMode\Observe\Event;
use App\Modules\CodeDesigner\ObserveMode\Observe\ObserveA;
use App\Modules\CodeDesigner\ObserveMode\Observe\ObserveB;
use App\Modules\CodeDesigner\ObserveMode\Worker;
use App\Modules\CodeDesigner\Prototype\Resume;
use Hyperf\Command\Command as HyperfCommand;
use Hyperf\Command\Annotation\Command;
use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Input\InputArgument;

/**
 * @Command
 */
#[Command]
class CodeDesignerCommand extends HyperfCommand
{

    protected $name = 'app:code';
    /**
     * @var ContainerInterface
     */
    protected $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;

        parent::__construct('app:code');
    }

    // php74 bin/hyperf.php app:code adapter-mode
    public function handle()
    {
        $argument = $this->input->getArgument('mode') ?? 'factory';
        switch ($argument) {
            case 'factory' :
                $operation = new OperationFactory();
                echo $operation->operation('+', 2, 3);
                break;
            case 'clone' :
                $resume = new Resume('yym', '27');
                $resume->setWork('2021-04-17', 'php');
                echo $resume->display();

                $resume2 = clone $resume;
                $resume2->setWork('2020-02-29', 'game');
                echo $resume2->display();
                break;
            case 'event-observe':
                $worker = new Worker();
                $worker->read(555);
                break;
            case 'observe':
                $event = new Event();
                $event->addObserve(new ObserveA());
                $event->addObserve(new ObserveB());
                $event->trigger();
                break;
            case 'abstract-factory':
                $factory = new BlackAnimalFactoryImpl();
                /**
                 * @var Cat $cat
                 */
                $cat = $factory->createCat();
                $cat->voice();
                $dog = $factory->createDog();
                $dog->voice();
                break;
            case 'reflection-factory':
                $factory = new FactoryReflection();
                $cat = $factory->createCat();
                $dog = $factory->createDog();
                $cat->voice();
                $dog->voice();
                break;
            case 'adapter-mode':
                // 小猫吃东西
                $cat = new Main(new CatAdapterImpl());
                echo $cat->eat();

                //小狗吃东西
                $dog = new Main(new DogAdapterImpl());
                echo $dog->eat();
                break;
            case 'IOC':
//                $container = new Container();
//                $container->bind('BoardInterface', function () {
//                    return new CommonKeyboard();
//                });
//                $container->bind('Computer', function ($container, $modules) use($container) {
//                    return new Computer($container->make($modules));
//                });
//                $container->make('Computer', ['BoardInterface']);
//                break;
            case 'memento':
                $originator = new Originator('我是发起人的初始化状态');
                $caretaker = new Caretaker($originator);

                $caretaker->backUp(); // 第一次备份
                $originator->doSomething();

                $caretaker->backUp();
                $originator->doSomething();

                $caretaker->backup();
                $originator->doSomething();

                echo "\n";
                $caretaker->showHistory();

                echo "\nClient: Now, let's rollback!\n\n";
                $caretaker->undo();

                echo "\nClient: Once more!\n\n";
                $caretaker->undo();
                break;
            case 'component':
                $simple = new Leaf();
                echo 'Result:::' . $simple->operation();

                echo "\n\n";

                /**
                 * ...as well as the complex composites.
                 */
                $tree = new Composite();
                $branch1 = new Composite();
                $branch1->add(new Leaf());
                $branch1->add(new Leaf());

                $branch2 = new Composite();
                $branch2->add(new Leaf());

                $tree->add($branch1);
                $tree->add($branch2);

                echo "Client: Now I've got a composite tree:\n";
                echo "tree & branch1 && branch2:::" . $tree->operation();
                echo "\n\n";
                break;
            default:
                throw new \Exception('ERROR');
        }
    }

    protected function getArguments()
    {
        return [
            ['mode', InputArgument::OPTIONAL, '这里是对这个参数的解释']
        ];
    }
}